package com.base.cn.platform.os.controller.op.coupon;

import com.base.cn.platform.os.common.controller.BaseController;
import com.base.cn.platform.os.common.mybatis.Pagination;
import com.base.cn.platform.os.common.utils.*;
import com.base.cn.platform.os.common.utils.order.ShopType;
import com.base.cn.platform.os.common.utils.result.ResultUtil;
import com.base.cn.platform.os.entity.op.coupon.OpCoupon;
import com.base.cn.platform.os.entity.op.coupon.OpCouponCode;
import com.base.cn.platform.os.entity.op.coupon.OpCouponTermShop;
import com.base.cn.platform.os.entity.op.coupon.CouponShopData;
import com.base.cn.platform.os.service.op.coupon.OpCouponBiz;
import com.base.cn.platform.os.service.op.coupon.OpCouponCodeBiz;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 优惠券ontroller
 *
 * @author ll
 * @create 2018-05-09
 */
@RestController
@RequestMapping("/manage/op")
public class OpCouponController extends BaseController {

    @Autowired
    private OpCouponBiz opCouponBiz;
    @Autowired
    private OpCouponCodeBiz opCouponCodeBiz;

    /**
     * 搜索课程列表
     * @param opCoupon
     * @param currentPage
     * @return
     */
    @RequestMapping("/queryOpCouponListPage")
    public PageInfo<OpCoupon> queryOpCouponListPage(@RequestBody OpCoupon opCoupon,
                                                    @RequestParam(value = "currentPage",required = false,defaultValue = "1")Integer currentPage,
                                                    @RequestParam(value = "subjectDate",required = false,defaultValue = "false")boolean subjectDate,
                                                    @RequestParam(value = "courseDate",required = false,defaultValue = "false")boolean courseDate,
                                                    @RequestParam(value = "openCourseDate",required = false,defaultValue = "false")boolean openCourseDate,
                                                    @RequestParam(value = "endTimeDay",required = false,defaultValue = "false")boolean endTimeDay){
        Pagination page = new Pagination();
        page.setCurrentPage(currentPage);
        return opCouponBiz.queryCouponListPage(opCoupon,page,subjectDate,courseDate,openCourseDate,endTimeDay);
    }

    /**
     * 搜索优惠券
     * @param opCoupon
     * @param subjectDate
     * @param courseDate
     * @param openCourseDate
     * @return
     */
    @RequestMapping("/queryOpCouponList")
    public List<OpCoupon> queryOpCouponList(@RequestBody OpCoupon opCoupon,
                                            @RequestParam(value = "subjectDate",required = false,defaultValue = "false")boolean subjectDate,
                                            @RequestParam(value = "courseDate",required = false,defaultValue = "false")boolean courseDate,
                                            @RequestParam(value = "openCourseDate",required = false,defaultValue = "false")boolean openCourseDate,
                                            @RequestParam(value = "endTimeDay",required = false,defaultValue = "false")boolean endTimeDay){
        return opCouponBiz.queryCouponList(opCoupon,subjectDate,courseDate,openCourseDate,endTimeDay);
    }

    /**
     * 添加优惠券
     * @param coupon
     * @return
     */
    @RequestMapping("/saveOpCoupon")
    public Map<String,Object> saveOpCoupon(@RequestBody OpCoupon coupon){
        if (ObjectUtils.isNotEmpty(coupon)) {
            String string = StringUtils.generatingLotNumberCoupon();
            coupon.setCouponBatch(string);
            if (StringUtils.isEmpty(coupon.getTitle())) {
                return ResultUtil.ERROR("请填写优惠券名称");
            }
            if (coupon.getCodeNum()==null||coupon.getCodeNum()<=0) {
                return ResultUtil.ERROR("请填写创建数量");
            }
            if (coupon.getCodeNum() > 10000) {
                return ResultUtil.ERROR("创建数量不能超过10000");
            }
            if (!StringUtils.isNumber(coupon.getCodeNum().toString())) {
                return ResultUtil.ERROR("请正优惠券编码数量只能为正整数");
            }
            if (coupon.getType()==null||coupon.getType()<=0) {
                return ResultUtil.ERROR("请选择优惠券类型");
            }
            if (coupon.getType() == 2) {
                if (coupon.getLimitAtion() > coupon.getMinAmount()) {
                    return ResultUtil.ERROR("优惠金额不能大于最低消费限额");
                }
            }
            if (coupon.getLimitAtion()==null||coupon.getLimitAtion()<=0.0) {
                return ResultUtil.ERROR("请填写优惠金额/折扣");
            }
            if (coupon.getType() == 1) { // 折扣券
                if (coupon.getLimitAtion() <= 0.0 || coupon.getLimitAtion() > 10.0) {
                    return ResultUtil.ERROR("请正确填写优惠券折扣数值(大于0小于等于10)");
                }
            }
            if (coupon.getType() == 2) { // 定额券
                if (!isDecimalAndInteger(coupon.getLimitAtion().toString())) {
                    return ResultUtil.ERROR("请正确填写优惠券金额");
                }
            }
            if (coupon.getMinAmount()==null||coupon.getMinAmount()<=0) {
                return ResultUtil.ERROR("请填写最低限额");
            }
            if (!isDecimalAndInteger(coupon.getMinAmount().toString())) {
                return ResultUtil.ERROR("请正确填写最低限额 格式（99.99 或 9999）");
            }
            if(coupon.getSettingStatus().intValue()==1){//有使用条件
                CouponShopData shopData = coupon.getShopData();
                if(!ObjectUtils.isNotEmpty(shopData)){
                    return ResultUtil.ERROR("请设置使用条件");
                }
                String courseIds = shopData.getCourseIds();
                String examIds = shopData.getExamIds();
                String bookIds = shopData.getBookIds();
                String memberIds = shopData.getMemberIds();
                String qaUse = shopData.getQaUse();
                String attendUse = shopData.getAttendUse();
                if(!StringUtils.isNotEmpty(courseIds)
                        && !StringUtils.isNotEmpty(examIds)
                        && !StringUtils.isNotEmpty(bookIds)
                        && !StringUtils.isNotEmpty(memberIds)
                        && qaUse.equals("off")
                        && attendUse.equals("off")){
                    return ResultUtil.ERROR("请设置使用条件");
                }
            }
            if (coupon.getTimeType()==null||coupon.getTimeType()<=0) {
                return ResultUtil.ERROR("请选择时间类型");
            }
            if (coupon.getTimeType() == 1) {
                if (!ObjectUtils.isNotEmpty(coupon.getBeginTime())) {
                    return ResultUtil.ERROR("请填写开始时间");
                }
                if (!ObjectUtils.isNotEmpty(coupon.getEndTime())) {
                    return ResultUtil.ERROR("请填写结束时间");
                }
                if (coupon.getBeginTime().getTime() > coupon.getEndTime().getTime()) {
                    return ResultUtil.ERROR("开始时间不能大于结束时间");
                }
            }
            if (StringUtils.isEmpty(coupon.getSummary())) {
                return ResultUtil.ERROR("请填写优惠券描述");
            }
            //判断推广条件
            if(coupon.getReceiveType().intValue()==2){//定向发放
                if(coupon.getOrientType().intValue() ==1){//针对用户
                    if(coupon.getUserType().intValue() ==2){//部分用户
                        List<OpCouponTermShop> termShopList = coupon.getOpCouponTermShopList();
                        if(!ObjectUtils.isNotEmpty(termShopList)){
                            return ResultUtil.ERROR("请添加指定的商品");
                        }
                        Map<String,List<OpCouponTermShop>> termShopMap = termShopList.stream().collect(Collectors.groupingBy(e->e.getShopType()));
                        List<OpCouponTermShop> courseList = termShopMap.get(ShopType.ORDER_SHOP_COURSE);
                        if(ObjectUtils.isNotEmpty(courseList) && courseList.size() > 10){
                            return ResultUtil.ERROR("最多可添加10个课程商品");
                        }
                        List<OpCouponTermShop> examList = termShopMap.get(ShopType.ORDER_SHOP_EXAM);
                        if(ObjectUtils.isNotEmpty(examList) && examList.size() > 10){
                            return ResultUtil.ERROR("最多可添加10个试卷商品");
                        }
                        List<OpCouponTermShop> bookList = termShopMap.get(ShopType.ORDER_SHOP_BOOK);
                        if(ObjectUtils.isNotEmpty(bookList) && bookList.size() > 10){
                            return ResultUtil.ERROR("最多可添加10个图书商品");
                        }
                        List<OpCouponTermShop> memberList = termShopMap.get(ShopType.ORDER_SHOP_MEMBER);
                        if(ObjectUtils.isNotEmpty(memberList) && memberList.size() > 10){
                            return ResultUtil.ERROR("最多可添加10个会员商品");
                        }
                    }
                }else if(coupon.getOrientType().intValue() ==2){//针对场景
                    if(coupon.getConditions()==null || coupon.getConditions().intValue() ==0){
                        return ResultUtil.ERROR("请选择针对发放的场景");
                    }
                }
            }
            coupon =opCouponBiz.txSaveCoupon(coupon);
        }
        return ResultUtil.SUCCESS("添加成功",coupon);
    }


    /**
     * 搜索优惠券详情
     * @param id
     * @return
     */
    @RequestMapping("/queryOpCouponById")
    public OpCoupon queryOpCouponById(@RequestParam("id")BigDecimal id,
                                      @RequestParam(value = "subjectDate",required = false,defaultValue = "false")boolean subjectDate,
                                      @RequestParam(value = "courseDate",required = false,defaultValue = "false")boolean courseDate,
                                      @RequestParam(value = "openCourseDate",required = false,defaultValue = "false")boolean openCourseDate,
                                      @RequestParam(value = "endTimeDay",required = false,defaultValue = "false")boolean endTimeDay){
        return opCouponBiz.queryOpCouponById(id,subjectDate,courseDate,openCourseDate,endTimeDay);
    }


    /**
     * 修改状态
     * @param couponIds
     * @param status
     * @return
     */
    @RequestMapping("/updateOpCouponStatus")
    public Map<String,Object> updateOpCouponStatus(@RequestParam("couponIds")String couponIds,
                                                     @RequestParam("status")Integer status){
        List<OpCoupon> couponList = opCouponBiz.updateCouponStatus(couponIds,status);
        if(!ObjectUtils.isNotEmpty(couponList)){
            return ResultUtil.ERROR("没有可操作的优惠券");
        }
        String message = "";
        if (status ==1){
            message ="恢复成功";
        }else if (status ==2){
            message ="停止成功";
        }else if (status ==3){
            message ="删除成功";
        }
        return ResultUtil.SUCCESS(message,couponList);
    }

    /**
     * 赠送Coupon优惠券
     * @param userIds
     * @return
     */
    @RequestMapping("/presentOpCoupon")
    public Map<String,Object> presentOpCoupon(@RequestParam("userIds")String userIds,
                                              @RequestParam("couponId")BigDecimal couponId){
        userIds = StringUtils.subHeadTailString(userIds,",");
        userIds = Stream.of(userIds.split(",")).filter(StringUtils::isNumber).collect(Collectors.joining(","));
        if (StringUtils.isEmpty(userIds)) {
            return ResultUtil.ERROR("请选择赠送的学员");
        }
        String[] splits = userIds.split(",");
        List<OpCouponCode> couponList = opCouponCodeBiz.queryOpCouponCodeByGiftCardIdAndStatusAndIsUserData(couponId,1,null,splits.length);
        if (!ObjectUtils.isNotEmpty(couponList)) {
            return ResultUtil.ERROR("选择的优惠券已无可赠数量");
        }
        if (splits.length > couponList.size()) {
            return ResultUtil.ERROR("选择用户超过优惠券总量");
        }
        for (int i = 0, size = splits.length; i < size; i++) {
            couponList.get(i).setUserId(new BigDecimal(splits[i]));
        }
        opCouponBiz.presentCoupon(couponList);
        return ResultUtil.SUCCESS("操作成功");
    }

    /**
     * 获取课程详情可以领取的优惠券列表
     * @param courseId 课程ID
     * @return List<OpCoupon>
     */
    @RequestMapping("/getCourseCouponList")
    public List<OpCoupon> getCourseCouponList(@RequestParam("courseId") BigDecimal courseId,
                                              @RequestParam(value = "userId",required = false,defaultValue = "0") BigDecimal userId){
        return opCouponBiz.getCourseCouponList(courseId,userId);
    }

    /**
     * 用户领取优惠券
     * @param couponIds 优惠券ID串
     * @param userId 用户ID
     * @return Map<String,Object>
     */
    @RequestMapping("/couponReceive")
    public Map<String,Object> couponReceive(@RequestParam("couponIds") String couponIds,
                                     @RequestParam("userId") BigDecimal userId){
        List<OpCouponCode> couponCodeList = opCouponCodeBiz.findCouponCodeReceive(couponIds,userId);
        if(ObjectUtils.isNotEmpty(couponCodeList)){
            Map<String,List<OpCouponCode>> couponCodeListMap = couponCodeList.stream().collect(Collectors.groupingBy(e->e.getReceiveStatus()));
            //获取可以领取的优惠券列表
            List<OpCouponCode> yList = couponCodeListMap.get("Y");
            if(ObjectUtils.isNotEmpty(yList)){
                yList.forEach(e->e.setUserId(userId));
                opCouponCodeBiz.updateBatch(yList);
                return ResultUtil.SUCCESS("优惠券领取成功");
            }else{
                return ResultUtil.ERROR("您已领取过该优惠券");
            }
        }
        return ResultUtil.ERROR("优惠券已被全部领取");
    }

    /**
     * 获取针对用户可以领取的优惠券
     * @param userId 用户ID
     * @return Map<String,Object>
     */
    @RequestMapping("/findForUsersCouponList")
    public Map<String,Object> findForUsersCouponList(@RequestParam("userId") BigDecimal userId){
        if(DataUtil.idIsNotNull(userId)){
            List<OpCoupon> couponList = new ArrayList<>();
            List<OpCoupon> _list = opCouponBiz.findAllUserReceiveCouponList(userId);
            if(ObjectUtils.isNotEmpty(_list)){
                couponList.addAll(_list);
            }
            List<OpCoupon> list = opCouponBiz.findPartPayShopUserReceiveCouponList(userId);
            if(ObjectUtils.isNotEmpty(list)){
                couponList.addAll(list);
            }
            if(ObjectUtils.isNotEmpty(couponList)){
                return ResultUtil.SUCCESS(couponList);
            }else{
                return ResultUtil.ERROR("没有可领取的优惠券");
            }
        }
        return ResultUtil.ERROR("请登录再操作");
    }

    //=====================================================================
    private boolean isDecimalAndInteger(String str) {
        //检查是否为空
        return !StringUtils.isEmpty(str) && Pattern.matches("^\\d+\\.?\\d{0,2}$", str);
    }

    /**
     *
     * @param opCouponCode 优惠券批次ID 条件
     * @return
     * @throws IOException
     */
    @RequestMapping("/downloadExcelOpCouponCodeList")
     public  ResponseEntity<byte[]> downloadExcelOpCoupon(@RequestBody OpCouponCode opCouponCode) throws IOException{
        String [] titles = {"ID","优惠券名称","优惠券批次","优惠券类型","获取条件","优惠券编码","状态","使用时间","持有用户","手机号"};
        OpCoupon opCoupon = opCouponBiz.queryOpCouponById(opCouponCode.getCouponId(), false, false, false, false);
        List<OpCouponCode> opCouponCodes = opCouponCodeBiz.queryUserCouponCodeList(opCouponCode, true, true);

        return   FileExportImportUtil.exportExcel(titles,getData(opCoupon,opCouponCodes),opCoupon.getTitle()+"-优惠券");
    }

    private List<List<String>> getData(OpCoupon opCoupon, List<OpCouponCode> couponCodeList){
        List<List<String>> data = new ArrayList<>();
        if(ObjectUtils.isNotEmpty(opCoupon)){
            if(ObjectUtils.isNotEmpty(couponCodeList)){
                String type ="";
                switch (opCoupon.getType()){
                    case 1:
                        type="折扣券";
                        break;
                    case 2:
                        type="定额";
                        break;
                }
                String conditions ="";
                switch (opCoupon.getConditions()){
                    case 1:
                        conditions="手动发放";
                        break;
                    case 2:
                        conditions="新用户注册后自动获取";
                        break;
                    case 3:
                        conditions="学员生日获取";
                        break;
                    case 4:
                        conditions="邀请注册获取";
                        break;
                    case 5:
                        conditions="消费任意金额获取";
                        break;
                    case 6:
                        conditions="免费直播发放";
                        break;
                    case 7:
                        conditions="活动";
                        break;
                }
                String finalType = type;
                String finalConditions = conditions;
                String title = opCoupon.getTitle();
                String couponBatch = opCoupon.getCouponBatch();
                couponCodeList.forEach(v->{

                    String status ="";
                    switch (v.getStatus()){
                        case 1:
                            status="已正常";
                            break;
                        case 2:
                            status="已冻结";
                            break;
                        case 3:
                            status="已删除";
                            break;
                        case 4:
                            status="已作废";
                            break;
                        case 5:
                            status="已使用";
                            break;
                        case 6:
                            status="已停止";
                            break;
                    }
                    Map<String, Object> user= v.getUser();
                    data.add(Arrays.asList(
                            v.getId().toString(),
                            title,
                            couponBatch,
                            finalType,
                            finalConditions,
                            v.getCode(),
                            status,
                            ObjectUtils.isNotEmpty(v.getUseTime())? DateUtils.format(v.getUseTime()) :"",
                            ObjectUtils.isNotEmpty(user)?user.get("nickname").toString():"",
                            ObjectUtils.isNotEmpty(user)?ObjectUtils.isNotEmpty(user.get("mobile"))?user.get("mobile").toString():"":""

                    ));
                });
            }
        }
        return data;
    }
}
